package cn.bone.mima.rsa;

import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.util.Base64;

public class SignatureDemo {

    public static void main(String[] args) throws Exception{

        String input = "123";
        String algorithm = "RSA";
        String pubPath = "e:/test/rsa/a.pub";
        String priPath = "e:/test/rsa/b.pri";
        // 签名算法
        String signAlgorithm = "sha256withrsa";

        // 获取公钥和私钥
        PublicKey publicKey = RsaDemo.readPublicKey(pubPath, algorithm);
        PrivateKey privateKey = RsaDemo.readPrivateKey(priPath, algorithm);

        String signature = getSignature(input, signAlgorithm, privateKey);
        System.out.println(signature);
        boolean b = verifySignature(input, signAlgorithm, publicKey, signature);
        System.out.println(b);
    }

    /**
     * 生成数字签名
     * @param input         表示原文
     * @param signAlgorithm 表示签名算法
     * @param privateKey    私钥
     * @return
     */
    private static String getSignature(String input,
                                       String signAlgorithm,
                                       PrivateKey privateKey) throws Exception{
        // 获取签名对象 使用 Signature
        Signature signature = Signature.getInstance(signAlgorithm);
        // 初始化签名
        signature.initSign(privateKey);
        // 传入明文
        signature.update(input.getBytes());
        // 开始签名
        byte[] sign = signature.sign();
        // base64编码
        String result = Base64.getEncoder().encodeToString(sign);
        return result;
    }

    /**
     * 校验数字签名
     * @param input             原文
     * @param signAlgorithm     签名算法
     * @param publicKey         公钥
     * @param signatureDate     使用私钥签名后得到的数字签名
     * @return
     * @throws Exception
     */
    private static boolean verifySignature(String input,
                                           String signAlgorithm,
                                           PublicKey publicKey,
                                           String signatureDate) throws Exception{
        // 获取签名对象 使用 Signature
        Signature signature = Signature.getInstance(signAlgorithm);
        signature.initVerify(publicKey);
        signature.update(input.getBytes());
        byte[] decode = Base64.getDecoder().decode(signatureDate);
        boolean verify = signature.verify(decode);
        return verify;
    }
}
